package com.wss.lsl.test.driven.concurrent;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * 可安全关闭的日志服务<br>
 * 同一个不变约束用同一个锁保护
 * 
 * @author sean
 * 
 */
public class LoggerService {

	private LoggerThread loggerThread;
	private BlockingQueue<String> queue;
	private PrintWriter writer;
	private boolean shutdownRequest = false;
	private int reservations = 0;
	private static int LOGGER_CAPACITY = 1000;

	public LoggerService() throws IOException {
		loggerThread = new LoggerThread();
		queue = new LinkedBlockingQueue<String>(LOGGER_CAPACITY);
		this.writer = new PrintWriter(System.out, true);
	}

	public void start() {
		loggerThread.start();
	}

	public void stop() {
		synchronized (this) {
			shutdownRequest = true;
		}
		loggerThread.interrupt();
	}

	public void log(String msg) throws InterruptedException {
		synchronized (this) {
			if (shutdownRequest) {
				throw new IllegalStateException("loggerService is stoped!");
			}
			reservations++;
		}
		queue.put(msg);
	}

	private class LoggerThread extends Thread {

		@Override
		public void run() {
			try {
				while (true) {
					try {
						synchronized (LoggerService.this) {
							if (shutdownRequest && reservations == 0) {
								break;
							}
						}
						String msg = queue.take();
						synchronized (LoggerService.this) {
							reservations--;
						}
						writer.println(msg);
						// System.out.println(msg);
					} catch (InterruptedException e) {
						/* 继续 */
					}
				}
			} finally {
				writer.close();
			}
		}
	}
}
